//
//  ImageUtil.m
//  Weike
//
//  Created by leirz on 14-6-17.
//  Copyright (c) 2014年 winupon. All rights reserved.
//

#import "ImageUtil.h"

@implementation ImageUtil

+ (UIImage *)compress:(UIImage *)image newWidth:(int)newWidth
{
    int oldWidth = image.size.width;
    int oldHeight = image.size.height;
    if (oldWidth <= newWidth) {
        return image;
    }
    int newHeight =  newWidth  * oldHeight / oldWidth;
    return [self drawInRect:image width:newWidth height:newHeight];
}

+ (UIImage *)compress:(UIImage *)image newHeight:(int)newHeight
{
    int oldWidth = image.size.width;
    int oldHeight = image.size.height;
    if (oldHeight <= newHeight) {
        return image;
    }
    int newWidth =  newHeight  * oldWidth / oldHeight;
    return [self drawInRect:image width:newWidth height:newHeight];
}


+ (UIImage *)drawInRect:(UIImage *)image width:(int)width height:(int)height
{
    CGRect rect = CGRectMake(0, 0, width, height);
    UIGraphicsBeginImageContext(rect.size);
    [image drawInRect:rect];
    UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    //    CGImageRelease(image.CGImage);
    return newImage;
}

+ (UIImage *)compress:(UIImage *)image newWidth:(int)newWidth newHeight:(int)newHeight
{
    int oldWidth = image.size.width;
    int oldHeight = image.size.height;
    if (oldWidth <= newWidth && oldHeight <= newHeight) {
        return image;
    }
    CGFloat oldRate = oldHeight * 1.0 / oldWidth;
    CGFloat minRate = 1.0 / 3;
    if (oldRate <= 3 && oldRate >= minRate) {
        if (oldWidth > newWidth) {
            newHeight = newWidth * oldHeight / oldWidth;
        } else if (oldHeight > newHeight) {
            newWidth = newHeight * oldWidth / oldHeight;
        }
        return [self drawInRect:image width:newWidth height:newHeight];
    } else {//极端
        int cutWidth = newWidth;
        int cutHeight = newHeight;
        UIImage *newImage = nil;
        if (oldRate > 3) {
            if (oldWidth > newWidth / 3) {
                newWidth = newWidth / 3;
                newHeight = newWidth * oldHeight / oldWidth;
                cutWidth = newWidth;
                newImage = [self drawInRect:image width:newWidth height:newHeight];
            } else {
                cutWidth = oldWidth;
                newImage = image;
            }
        } else if (oldRate < minRate) {
            if (oldHeight > newHeight / 3) {
                newHeight = newHeight / 3;
                newWidth = newHeight * oldWidth / oldHeight;
                cutHeight = newHeight;
                newImage = [self drawInRect:image width:newWidth height:newHeight];
            } else {
                cutHeight = oldHeight;
                newImage = image;
            }
        }
        CGImageRef imageRef = CGImageCreateWithImageInRect(newImage.CGImage, CGRectMake(0, 0, cutWidth, cutHeight));
        newImage = [UIImage imageWithCGImage:imageRef];
        CGImageRelease(imageRef);
        return newImage;
    }
}

+ (UIImage *)cutImage:(UIImage *)image width:(int)width
{
    int oldWidth = image.size.width;
    int oldHeight = image.size.height;
    if (oldWidth == width && oldHeight == width) {
        return image;
    }
    int newWidth = width;
    int newHeight = width;
    if (oldWidth > oldHeight) {
        newWidth = newHeight * oldWidth / oldHeight;
    } else if (oldWidth < oldHeight) {
        newHeight = newWidth * oldHeight / oldWidth;
    }
    UIImage *newImage = [self drawInRect:image width:newWidth height:newHeight];
    int x = 0;
    int y = 0;
    if (newWidth > newHeight) {
        x = (newWidth - width) / 2;
    } else if (newWidth < newHeight) {
        y = (newHeight - width) / 2;
    }
    CGImageRef imageRef = CGImageCreateWithImageInRect(newImage.CGImage, CGRectMake(x, y, width, width));
    newImage = [UIImage imageWithCGImage:imageRef];
    CGImageRelease(imageRef);
    return newImage;
}

+ (UIImage *)cutImage:(UIImage *)image withScale:(float)scale
{
    CGFloat oldWidth = image.size.width;
    CGFloat oldHeight = image.size.height;
    
    if (oldHeight/oldWidth == scale) {
        return image;
    }
    float x=0;
    float y=0;
    CGFloat newWidth = oldWidth;
    CGFloat newHeight =oldHeight;
    
    if(oldHeight/oldWidth > scale){ //高太长，截取高
        newHeight = newWidth*scale;
        y =(oldHeight-newHeight)/2;
    }else if (oldHeight/oldWidth < scale){//宽太长，截取宽
        newWidth =newHeight/scale;
        x=(oldWidth-newWidth)/2;
    }
    
    CGImageRef imageRef = CGImageCreateWithImageInRect(image.CGImage, CGRectMake(x, y, newWidth, newHeight));
    UIImage *newImage = [UIImage imageWithCGImage:imageRef];
    CGImageRelease(imageRef);
    return newImage;
}

+(UIImage *)blurryImage:(UIImage *)img withBlurLevel:(CGFloat)blur
{
    CIContext *context = [CIContext contextWithOptions:nil];
    CIImage *inputImage = [[CIImage alloc] initWithImage:img];
    // create gaussian blur filter
    CIFilter *filter = [CIFilter filterWithName:@"CIGaussianBlur"];
    [filter setValue:inputImage forKey:kCIInputImageKey];
    [filter setValue:[NSNumber numberWithFloat:blur] forKey:@"inputRadius"];
    // blur image
    CIImage *result = [filter valueForKey:kCIOutputImageKey];
    CGImageRef cgImage = [context createCGImage:result fromRect:inputImage.extent];
    UIImage *returnImage = [UIImage imageWithCGImage:cgImage];
    CGImageRelease(cgImage);
    return  returnImage;
}


+(UIImage*) BgImageFromColors:(NSArray*)colors withFrame: (CGRect)frame
{
    
    NSMutableArray *ar = [NSMutableArray array];
    
    for(UIColor *c in colors) {
        
        [ar addObject:(id)c.CGColor];
        
    }
    
    UIGraphicsBeginImageContextWithOptions(frame.size, YES, 1);
    
    CGContextRef context = UIGraphicsGetCurrentContext();
    
    CGContextSaveGState(context);
    
    CGColorSpaceRef colorSpace = CGColorGetColorSpace([[colors lastObject] CGColor]);
    
    CGGradientRef gradient = CGGradientCreateWithColors(colorSpace, (CFArrayRef)ar, NULL);
    
    CGPoint start;
    
    CGPoint end;
    
    start = CGPointMake(0.0, frame.size.height);
    
    end = CGPointMake(frame.size.width, 0.0);
    
    CGContextDrawLinearGradient(context, gradient, start, end,kCGGradientDrawsBeforeStartLocation | kCGGradientDrawsAfterEndLocation);
    
    UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
    
    CGGradientRelease(gradient);
    
    CGContextRestoreGState(context);
    
    CGColorSpaceRelease(colorSpace);
    
    UIGraphicsEndImageContext();
    
    return image;
}

+(UIImage *)getPartOfImage:(UIImage *)img rect:(CGRect)partRect
{
    CGImageRef imageRef = img.CGImage;
    CGImageRef imagePartRef = CGImageCreateWithImageInRect(imageRef, partRect);
    UIImage *retImg = [UIImage imageWithCGImage:imagePartRef];
    CGImageRelease(imagePartRef);
    return retImg;
}


+ (UIImage *)scaleToSize:(UIImage *)img size:(CGSize)size{
    // 创建一个bitmap的context
    // 并把它设置成为当前正在使用的context
    UIGraphicsBeginImageContext(size);
    // 绘制改变大小的图片
    [img drawInRect:CGRectMake(0, 0, size.width, size.height)];
    // 从当前context中创建一个改变大小后的图片
    UIImage* scaledImage = UIGraphicsGetImageFromCurrentImageContext();
    // 使当前的context出堆栈
    UIGraphicsEndImageContext();
    // 返回新的改变大小后的图片
    return scaledImage;
}


+ (UIImage*)grayImage:(UIImage*)image
{
    // Adapted from this thread: http://stackoverflow.com/questions/1298867/convert-image-to-grayscale
    const int RED = 1;
    const int GREEN = 2;
    const int BLUE = 3;
    
    // Create image rectangle with current image width/height
    CGRect imageRect = CGRectMake(0, 0, image.size.width * image.scale, image.size.height * image.scale);
    
    int width = imageRect.size.width;
    int height = imageRect.size.height;
    
    // the pixels will be painted to this array
    uint32_t *pixels = (uint32_t *) malloc(width * height * sizeof(uint32_t));
    
    // clear the pixels so any transparency is preserved
    memset(pixels, 0, width * height * sizeof(uint32_t));
    
    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
    
    // create a context with RGBA pixels
    CGContextRef context = CGBitmapContextCreate(pixels, width, height, 8, width * sizeof(uint32_t), colorSpace,
                                                 kCGBitmapByteOrder32Little | kCGImageAlphaPremultipliedLast);
    
    // paint the bitmap to our context which will fill in the pixels array
    CGContextDrawImage(context, CGRectMake(0, 0, width, height), [image CGImage]);
    
    for(int y = 0; y < height; y++) {
        for(int x = 0; x < width; x++) {
            uint8_t *rgbaPixel = (uint8_t *) &pixels[y * width + x];
            
            // convert to grayscale using recommended method: http://en.wikipedia.org/wiki/Grayscale#Converting_color_to_grayscale
            uint32_t gray = 0.2126 * rgbaPixel[RED] + 0.7152 * rgbaPixel[GREEN] + 0.0722 * rgbaPixel[BLUE];
            
            // set the pixels to gray
            rgbaPixel[RED] = gray;
            rgbaPixel[GREEN] = gray;
            rgbaPixel[BLUE] = gray;
        }
    }
    
    // create a new CGImageRef from our context with the modified pixels
    CGImageRef imageRef = CGBitmapContextCreateImage(context);
    
    // we're done with the context, color space, and pixels
    CGContextRelease(context);
    CGColorSpaceRelease(colorSpace);
    free(pixels);
    
    // make a new UIImage to return
    UIImage *resultUIImage = [UIImage imageWithCGImage:imageRef
                                                 scale:image.scale
                                           orientation:UIImageOrientationUp];
    
    // we're done with image now too
    CGImageRelease(imageRef);
    
    return resultUIImage;
}

+ (UIImage *)imageFromView:(UIView *)view
{
    UIGraphicsBeginImageContextWithOptions(view.frame.size, NO, 0.0);
    CGContextRef context = UIGraphicsGetCurrentContext();
    [view.layer renderInContext:context];
    UIImage *theImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return theImage;
}

@end
